package com.ruoyi.api.api;


import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class RedisKeyExpirationMonitor {

    /**
     * 监控特定前缀的Key过期事件
     */
    public void redisKeyExpirationMonitor(String targetKeyPrefix, String redisHost, int redisPort,
                                          String password, int database, RedisKeyExpirationCallback callback) {
        try (Jedis jedis = new Jedis(redisHost, redisPort)) {
            // 验证密码
            if (password != null && !password.isEmpty()) {
                jedis.auth(password);
            }

            // 选择数据库
            jedis.select(database);

            // 启用键空间通知（确保包含"Ex"）
            jedis.configSet("notify-keyspace-events", "Ex");

            final StringBuilder result = new StringBuilder();
            result.append("已连接到数据库 ").append(database).append("\n");

            // 创建订阅线程
            Thread subscriberThread = new Thread(() -> {
                try (Jedis subscriberJedis = new Jedis(redisHost, redisPort)) {
                    // 订阅连接也需要验证密码和选择数据库
                    if (password != null && !password.isEmpty()) {
                        subscriberJedis.auth(password);
                    }
                    subscriberJedis.select(database);

                    JedisPubSub pubSub = new JedisPubSub() {
                        public void onPSubscribe(String pattern, int subscribedChannels) {
                            System.out.printf("已订阅数据库 %d 中的所有过期事件%n", database);
                            result.append("已启动监控，等待以 ").append(targetKeyPrefix).append(" 为前缀的Key过期事件...\n");
                        }

                        public void onPMessage(String pattern, String channel, String expiredKey) {
                            // 检查过期Key是否匹配前缀
                            if (expiredKey.startsWith(targetKeyPrefix)) {
                                String eventMsg = String.format("检测到数据库 %d 中的Key [%s] 已过期%n",
                                        database, expiredKey);
                                System.out.print(eventMsg);
                                result.append(eventMsg);

                                // 调用回调方法
                                if (callback != null) {
                                    callback.onKeyExpired(expiredKey);
                                }
                            }
                        }
                    };

                    // 订阅所有过期事件
                    subscriberJedis.psubscribe(pubSub, "__keyevent@" + database + "__:expired");

                } catch (Exception e) {
                    String errorMsg = "订阅过程中发生错误: " + e.getMessage();
                    System.err.println(errorMsg);
                    result.append(errorMsg).append("\n");
                }
            });

            subscriberThread.setDaemon(true);
            subscriberThread.start();

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }


}
